home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pr2fl.arc / PR2FL.ASM next >
Assembly Source File  |  1985-07-13  |  7KB  |  283 lines

  1. PAGE    ,132
  2. TITLE    PR2FL - PRINTER REDIRECTION
  3. SUBTTL    By Jim Kyle - May 28, 1985 - Version 1.0
  4. ;
  5. ;    This program redirects PRN output to a file. The filename is
  6. ;    supplied as a pathname when the program is invoked:
  7. ;
  8. ;            PR2FL C:\FILES\PRTFIL.001
  9. ;
  10. ;    It achieves this goal by opening the file, saving the file's
  11. ;    DCB index (the content of its handle), and then faking an entry
  12. ;    in the handle table of its Program Segment Prefix to show that
  13. ;    the file is closed. Next, it extracts the content of the PRN
  14. ;    handle and saves it on the stack, stuffs the file's DCB index
  15. ;    into the PRN handle entry, and spawns a child copy of COMMAND.COM
  16. ;    to permit continued operation. While the child copy is running,
  17. ;    or any program called through the child copy is executing, all
  18. ;    output directed to the PRN device via standard DOS interfaces will
  19. ;    go instead to the redirection file.
  20. ;
  21. ;    To terminate redirection, the child copy of COMMAND.COM is
  22. ;    stopped via the EXIT command. Control then returns to PR2FL.COM,
  23. ;    which closes the redirection file, restores the original PRN index
  24. ;    value, displays a "Redirection Ended" message, and then returns
  25. ;    control to the copy of COMMAND.COM from which it was invoked.
  26. ;
  27. ;    This process inherently permits nesting. Each invocation of this
  28. ;    program takes away approximately 4K of RAM for the duration of
  29. ;    its execution (specifically, 3920 bytes). You can nest calls of
  30. ;    PR2FL as deeply as you have RAM available, and at each EXIT they
  31. ;    will automatically unwind themselves.
  32. ;
  33. ;    To assemble, use MASM, LINK, and EXE2BIN. If you find this
  34. ;    program useful, let me know. And if you find any bugs, by all
  35. ;    means tell me about them!
  36. ;                    Jim Kyle
  37. ;                    76703,762
  38. ;                    SysOp, CLM SIG (GO CLM-332)
  39. ;
  40. PAGE
  41. ;
  42. CODE    SEGMENT    PUBLIC 'CODE'
  43.      ASSUME    CS:CODE,DS:CODE,ES:CODE,SS:CODE
  44.  
  45.      ORG    0100H
  46.  
  47. START:     MOV    SP,OFFSET STACK         ;keep the stack safe
  48.     CALL    DOSVTST            ;verify proper DOS version
  49.     CALL    GETPATH            ;set up pointers to pathname
  50.     JNZ    HVPATH            ;error check here if no path
  51.     MOV    DX,OFFSET NOPATH
  52.     JMP    SHORT FINI
  53. HVPATH:    CALL    REDIR            ;get file and switch
  54.     PUSH    AX            ;save for use at return
  55.      MOV    CMDLNP+2,CS         ;initialize parm block
  56.      MOV    FCB1P+2,CS
  57.      MOV    FCB2P+2,CS
  58.     MOV    SAVSP,SP        ;save stack pointer
  59.     CALL    GETCOM            ;set up for COMSPEC (changes DS)
  60.     CALL    RELMEM            ;release unneeded RAM
  61.      MOV    DX,SI              ;DS:DX -> Pgm to run
  62.      MOV    BX,OFFSET PARMS         ;ES:BX -> Parm Block
  63.      MOV    AX,4B00H         ;AL=0  -> Execute program
  64.      INT    21H
  65.     MOV    AX,CS            ;restore segments
  66.     MOV    SS,AX
  67.     MOV    ES,AX
  68.     MOV    DS,AX
  69.     MOV    SP,SAVSP        ;restore stack pointer
  70.     MOV    BX,4            ;PRN handle (file)
  71.     MOV    AH,3EH            ;close the file
  72.     INT    21H
  73.     POP    AX            ;restore DCB indices
  74.     MOV    DI,1CH            ;handle table offset for PRN in PSP
  75.     MOV    [DI],AH            ;restore previous PRN
  76.      MOV    DX,OFFSET RTND         ;return message
  77. FINI:    PUSH    CS              ;restore DS
  78.      POP    DS
  79.      MOV    AH,9              ;send message
  80.      INT    21H
  81.      INT    20H              ;then get out for keeps
  82. PAGE
  83. ;
  84. RELMEM:
  85. LAST    =    OFFSET STACK+17
  86.      MOV    AX,OFFSET LAST         ;release surplus memory
  87.      SHR    AX,1              ;first convert to paragraphs
  88.      SHR    AX,1
  89.      SHR    AX,1
  90.      SHR    AX,1
  91.      MOV    BX,AX              ;then stash in BX
  92.      MOV    AX,4A00H
  93.      INT    21H
  94.     RET
  95. ;
  96. SAVSP    DW    0
  97. ;
  98. RTND    DB    13,10,'Redirection Ended',13,10,36
  99. ;
  100. PARMS    DW    0              ;env segment
  101. CMDLNP    DW    OFFSET CMDLIN,0         ;new command line
  102. FCB1P    DW    OFFSET FCB,0         ;new FCB1
  103. FCB2P    DW    OFFSET FCB,0         ;new FCB2
  104. ;
  105. CMDLIN    DB    CMDLEN              ;length of command
  106. ;    DB    'COMMAND /D'         ;command line
  107. CMDLEN    EQU    $-CMDLIN-1
  108.      DB    13              ;CR to terminate
  109. ;
  110. FCB    DB    0
  111.      DB    '           '
  112.      DW    0,0
  113. ;
  114.      DB    126 DUP (?)
  115. STACK    DW    0
  116. ;
  117. PAGE
  118. ;
  119. ;    THIS CODE USED ONLY DURING SETUP, NO NEED TO KEEP IT
  120. ;
  121. ;---module dosvtst.asm
  122. ;
  123. ;    verifies that DOS version is 2.0 or above, else aborts
  124. ;
  125. dosvtst:
  126.     mov    ah,30h         ;version check
  127.      int    21h
  128.      xchg    ah,al
  129.      cmp    ax,0200h    ;2.0 and above
  130.      jae    vrsnok
  131.      mov    dx,offset wvm
  132.      mov    ah,9
  133.      int    21h
  134.      int    20h
  135. wvm    db    'DOS 2.0 or above is required',13,10,'$'
  136. vrsnok:    ret             ;version is appropriate
  137. ;
  138. ;---end module dosvtst.asm
  139. ;
  140. PAGE
  141. ;
  142. ;---module getpath.asm
  143. ;
  144. ;    converts first string of command tail into ASCIIZ
  145. ;         pathname for DOS use.
  146. ;    destroys registers AX, CX, DX, SI, and DI
  147. ;    modifies flags
  148. ;
  149. GETPATH:
  150.      CLD
  151.      MOV    SI,80H         ;command tail in PSP
  152.      LODSB              ;get char count
  153.      AND    AL,127         ;test for no chars at all
  154.      JZ    PATH5         ;none, don't scan
  155.      CBW
  156.      MOV    CX,AX         ;else put into CX
  157. PATH0:    MOV    DX,SI         ;save start offset
  158.      MOV    DI,SI
  159.      LODSB              ;ignore leading blank
  160.      CMP    AL,' '
  161.      JA    PATH2         ;non-blank, go look for end
  162.      LOOP    PATH0         ;leading blank, look more
  163.      JMP    SHORT PATH4    ;nothing found
  164. ;
  165. PATH1:    MOV    DI,SI         ;save for case fix
  166.      LODSB              ;look for terminator
  167.      CMP    AL,' '
  168.      JBE    PATH4         ;found it
  169. PATH2:    CMP    AL,'a'         ;not seen, check case
  170.      JB    PATH3
  171.      CMP    AL,'z'
  172.      JA    PATH3
  173.      AND    AL,5FH         ;lowercase, make upper
  174.      STOSB
  175. PATH3:    LOOP    PATH1
  176.     INC    DI        ;to CR's location at EOS
  177. ;
  178. PATH4:    XOR    AL,AL         ;force a zero
  179.      MOV    [DI],AL
  180.     MOV    AX,DI
  181.      SUB    AX,DX
  182. PATH5:    RET             ;path converted
  183. ;
  184. ;    Z-flag is set if no pathname was present,
  185. ;    else:    AX = number of characters in pathname
  186. ;        CX = 0
  187. ;        DX points to pathname's first character
  188. ;        SI points to character past terminator (or NULL if no more)
  189. ;        DI points to terminating NULL of pathname
  190. ;
  191. ;---end module getpath.asm
  192. PAGE
  193. ;
  194. GETCOM:    MOV    SI,02CH              ;search Environment for COMSPEC
  195.      MOV    SI,[SI]
  196.      MOV    DS,SI
  197.      MOV    PARMS,SI         ;use parent's environment
  198.      MOV    SI,0
  199.      LODSB
  200. NXT:    MOV    BX,OFFSET ENVSTR
  201.      CMP    AL,ES:[BX]
  202.      JNZ    SKIP              ;no initial match
  203.      MOV    CX,7
  204. CHK:    LODSB
  205.      INC    BX
  206.      CMP    AL,ES:[BX]
  207.      JNZ    SKIP              ;failed after start
  208.      LOOP    CHK
  209.     RET                ;if we get here it's found
  210. ;
  211. ENVSTR    DB    'COMSPEC='
  212. ;
  213. SKIP:    LODSB                   ;find EOS
  214.      OR    AL,AL
  215.      JNZ    SKIP
  216.      LODSB                   ;test for end of Environment
  217.      OR    AL,AL
  218.      JNZ    NXT              ;more to check
  219.      MOV    DX,OFFSET NOENV         ;hit the end!
  220.      JMP    FINI
  221. ;
  222. NOPATH    DB    13,10,'Pathname is required',13,10,36
  223. NOENV    DB    13,10,'No COMSPEC= found',13,10,36
  224. ;
  225. PAGE
  226. ;
  227. REDIR:    MOV    CX,0
  228.     MOV    AH,3CH            ;create file
  229.     INT    21H
  230.     JC    DSKERR
  231.     MOV    BX,AX            ;handle
  232.     MOV    SI,18H            ;handle table offset in PSP
  233.     MOV    AL,[BX][SI]        ;DCB index for new file
  234.     MOV    [BX][SI],BYTE PTR 255    ;mark its handle as closed
  235.     MOV    AH,[SI][4]        ;DCB index for PRN handle
  236.     MOV    [SI][4],AL        ;set new file in as PRN
  237.     RET                ;if no error (indices in AX)
  238. ;
  239. DSKERR:
  240.     cmp    ax,19
  241.     jl    valerr
  242.     mov    dx,offset uem
  243.     jmp    short abrt
  244. valerr:    add    ax,ax
  245.     mov    bx,offset emt
  246.     add    bx,ax
  247.     mov    dx,[bx]
  248. abrt:    mov    ah,9
  249.     int    21h
  250.     mov    dx,offset emg2
  251.     mov    ah,9
  252.     int    21h
  253. done:    int    20h
  254. ;
  255. emg2    db    '.',13,10
  256.     db    'ABORTED.',7,13,10,'$'
  257. ;
  258. emt    dw    uem,em1,em2,em3,em4,em5,em6,em7
  259.     dw    em8,em9,em10,em11,em12,em13,uem
  260.     dw    em15,em16,em17,em18
  261. ;
  262. uem    db    'Unknown error code$'
  263. em1    db    'Bad call$'
  264. em2    db    'No file found$'
  265. em3    db    'Path not found$'
  266. em4    db    'Out of handles$'
  267. em5    db    'Access denied$'
  268. em6    db    'Handle bad$'
  269. em7    db    'Memory fouled$'
  270. em8    db    'No more RAM$'
  271. em9    db    'Bad adr$'
  272. em10    db    'Bad ENV$'
  273. em11    db    'Bad format$'
  274. em12    db    'Bad access code$'
  275. em13    db    'Bad data$'
  276. em15    db    'Drive not valid$'
  277. em16    db    'Dir error$'
  278. em17    db    'Wrong device$'
  279. em18    db    'Out of files$'
  280. ;
  281. CODE    ENDS
  282.      END    START
  283.